#include "UT_UTSoc.hpp"

#include "openvip/ovip.h"
#include "openvip_third/nutshell.h"
#include <cstdlib>
#include <queue>

using namespace ovip;

extern "C" {
    void sd_read(uint32_t *data);
    void sd_setaddr(uint32_t addr);
    void put_pixel(uint32_t pixel);
    void vmem_sync(void);
}

void sd_read(uint32_t *data) {
    Assert(false, "sd read")    
    Debug("SD read");
}
void sd_setaddr(uint32_t addr) {
    Assert(false, "sd setaddr")
    Debug("SD setaddr");
}

void put_pixel(uint32_t pixel) {
}

void vmem_sync(void) {
}

void test_raw_soc(){
    Debug("Test Soc")
    UTUTSoc *dut = new UTUTSoc();
    dut->initClock(dut->clock);

    MessageManager msgmgr(dut->xclk);
    SimpleBus2Message bus2msg("b2m", dut->port, {"io_mem_", "io_uart_"});
    DevMsgRam ram("ram");
    DevMsgUART uart("uart");
    ram.mem.LoadRaw("/home/yaozhicheng/workspace/OVIP-UT/mcv-ut/NutShell/ready-to-run/linux.bin", 0x80000000);

    msgmgr.AddSlaveDevice("io_mem_",   (Device&) ram);
    msgmgr.AddSlaveDevice("io_uart_",  (Device&) uart);
    msgmgr.AddMasterDevice("io_mem_",  (Device&) bus2msg);
    msgmgr.AddMasterDevice("io_uart_", (Device&) bus2msg);

    // reset
    dut->reset = 1;
    dut->xclk.Step(10000);
    dut->reset = 0;
    // run
    for(int i = 0; i < 100000000000; i++){
        dut->xclk.Step();
    }
    Debug("Test complete!")
}

int main(int argsc, const char **argsv)
{
    Info("Test cache ...");
    test_raw_soc();
    return 0;
}
